/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.serviportales.serviquality.managers;

import java.util.ArrayList;
import java.util.List;

import javax.swing.tree.DefaultMutableTreeNode;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.serviportales.serviportales.model.GenericNodeUserObject;
import com.serviportales.serviportales.model.GenericTreeModel;
import com.serviportales.serviquality.dao.CalProyectoNodoDAO;
import com.serviportales.serviquality.dao.PlantillaNodoDAO;
import com.serviportales.serviquality.dao.ProyectoDAO;
import com.serviportales.serviquality.dao.ProyectoNodoDAO;
import com.serviportales.serviquality.exception.ServiqualityException;
import com.serviportales.serviquality.model.CalProyectoNodo;
import com.serviportales.serviquality.model.Plantilla;
import com.serviportales.serviquality.model.PlantillaNodo;
import com.serviportales.serviquality.model.Proyecto;
import com.serviportales.serviquality.model.ProyectoNodo;
import com.serviportales.serviquality.model.ProyectoUser;

@Service
@Transactional(rollbackFor = { ServiqualityException.class })
public class MgrProyectos {

	public static String MSG_SELECCIONAR_PLANTILLA = "mgrProyectos.msg.seleccionarPlantilla";
	public static final String CALIFICAR_PROYECTO_ERROR = "mgrProyectos.error.calificarProyecto";

	@Autowired
	private ProyectoDAO proyectoDAO;
	@Autowired
	private MessageSource messageSource;
	@Autowired
	private PlantillaNodoDAO plantillaNodoDAO;
	@Autowired
	private ProyectoNodoDAO proyectoNodoDAO;
	@Autowired
	private CalProyectoNodoDAO calProyectoNodoDAO;
	@Autowired
	private MgrProyectoNodo mgrProyectoNodo;

	private ProyectoNodo plantillaNodoToProyectoNodo(PlantillaNodo plantillaNodo, Proyecto proyecto) {
		if (plantillaNodo == null) {
			return null;
		} else {
			ProyectoNodo proyectoNodo = new ProyectoNodo();
			proyectoNodo.getProyectoNodoPK().setNodo(plantillaNodo.getPlantillaNodoPK().getNodo());
			proyectoNodo.getProyectoNodoPK().setProyecto(proyecto);
			return proyectoNodo;
		}
	}

	public void grabarProyecto(Proyecto proyecto, Plantilla plantilla) throws ServiqualityException {
		try {
			Proyecto proyectoFilter = proyectoDAO.selectByID(proyecto.getCodigo());
			if (proyectoFilter != null) {
				proyectoFilter.setConclusion(proyecto.getConclusion());
				proyectoFilter.setDescripcion(proyecto.getDescripcion());
				proyectoFilter.setEstadoRegistro(proyecto.getEstadoRegistro());
				proyectoFilter.setNombre(proyecto.getNombre());
				proyectoDAO.update(proyectoFilter);
			} else {
				if (plantilla == null) {
					throw new ServiqualityException(messageSource.getMessage(MSG_SELECCIONAR_PLANTILLA, null, LocaleContextHolder.getLocale()));
				}

				// Consultar los nodos de la plantilla
				List<PlantillaNodo> nodosPlantilla = plantillaNodoDAO.selectCreateTree(plantilla);
				List<ProyectoNodo> nodosProyecto = new ArrayList<ProyectoNodo>();
				for (PlantillaNodo plantillaNodo : nodosPlantilla) {
					ProyectoNodo proyectoNodo = plantillaNodoToProyectoNodo(plantillaNodo, proyecto);
					proyectoNodo.setParent(plantillaNodoToProyectoNodo(plantillaNodo.getParent(), proyecto));
					nodosProyecto.add(proyectoNodo);
				}

				proyectoDAO.insert(proyecto);

				// Copiar los nodos al proyecto
				for (ProyectoNodo proyectoNodo : nodosProyecto) {
					proyectoNodoDAO.insert(proyectoNodo);
				}
			}
		} catch (ServiqualityException exception) {
			throw exception;
		} catch (Exception exception) {
			throw new ServiqualityException(messageSource.getMessage(ServiqualityException.GRABAR_ERROR, new String[] { exception.getMessage() }, LocaleContextHolder.getLocale()), exception);
		}
	}

	public List<Proyecto> buscarProyecto(Proyecto proyecto) throws ServiqualityException {
		try {
			return proyectoDAO.select(proyecto);
		} catch (Exception exception) {
			throw new ServiqualityException(messageSource.getMessage(ServiqualityException.BUSCAR_ERROR, new String[] { exception.getMessage() }, LocaleContextHolder.getLocale()), exception);
		}
	}

	@SuppressWarnings("unchecked")
	private void calificarNodo(DefaultMutableTreeNode treeNode) {
		GenericNodeUserObject<ProyectoNodo> userObject = (GenericNodeUserObject<ProyectoNodo>) treeNode.getUserObject();
		if (userObject.isLeaf()) {
			double calificacion = 0;
			List<CalProyectoNodo> calificaciones = calProyectoNodoDAO.selectByProyectoNodo(userObject.getValue());
			if (calificaciones.size() > 0) {
				for (CalProyectoNodo calProyectoNodo : calificaciones) {
					calificacion += calProyectoNodo.getCalificacion();
				}
				calificacion = (calificacion / calificaciones.size());
			}
			userObject.getValue().setCalificacion((long)calificacion);
		} else {
			double calificacion = 0;
			for (int i = 0; i < treeNode.getChildCount(); i++) {
				DefaultMutableTreeNode childNode = (DefaultMutableTreeNode) treeNode.getChildAt(i);
				calificarNodo(childNode);
				GenericNodeUserObject<ProyectoNodo> childUserObject = ((GenericNodeUserObject<ProyectoNodo>) childNode.getUserObject());
				double peso = (childUserObject.getValue().getPeso() != null) ? childUserObject.getValue().getPeso() : 0;
				calificacion += childUserObject.getValue().getCalificacion() * (peso / 100.0);				
			}
			userObject.getValue().setCalificacion((long)calificacion);
		}
	}

	@SuppressWarnings("unchecked")
	public Long actualizarCalificacion(Proyecto proyectoParam) throws ServiqualityException {
		try {
			Proyecto proyecto=proyectoDAO.selectByID(proyectoParam.getCodigo());
			ProyectoUser proyectoUserFilter = new ProyectoUser();
			proyectoUserFilter.getProyectoUserPK().setProyecto(proyecto);

			GenericTreeModel<ProyectoNodo> treeModel = mgrProyectoNodo.createTree(proyecto);
			calificarNodo((DefaultMutableTreeNode) treeModel.getRoot());

			for (DefaultMutableTreeNode defaultMutableTreeNode : treeModel.getElements().values()) {
				if (!defaultMutableTreeNode.equals((DefaultMutableTreeNode) treeModel.getRoot())) {
					if(((GenericNodeUserObject<ProyectoNodo>) defaultMutableTreeNode.getUserObject()).getValue().getCalificacion()>0){
						System.out.println(((GenericNodeUserObject<ProyectoNodo>) defaultMutableTreeNode.getUserObject()).getValue().getCalificacion());
					}
					proyectoNodoDAO.update(((GenericNodeUserObject<ProyectoNodo>) defaultMutableTreeNode.getUserObject()).getValue());
				}
			}

			proyecto.setCalificacion(treeModel.getRootNode().getCalificacion());

			proyectoDAO.update(proyecto);

			return proyecto.getCalificacion();
		} catch (Exception exception) {
			throw new ServiqualityException(messageSource.getMessage(CALIFICAR_PROYECTO_ERROR, new String[] { exception.getMessage() }, LocaleContextHolder.getLocale()), exception);
		}
	}
}
